/**
 * 会员管理
 */
var http = require('request'),
	sprintf = require("sprintf-js").sprintf,
	async = require('async');

var open189Config = require('../../config/open189');

(function() {

	var MemberController = {};
	var root = this;

	var accessToken = {
		token: null,
		endTime: 0
	}; //访问令牌

	/**
	 * 注册之前，基本校验
	 * @param  {Function} next
	 * @return {[type]}
	 */
	function validateSignup(next) {

		//必填字段校验
		if (!request.username) {
			return next('用户名没有输入!');
		}
		if (!request.password) {
			return next('密码没有输入!');
		}

		if (request.type === 'phone') {
			var reg = /^[1][345789]\d{9}$/;
			var phone = request.username;
			if (!reg.test(phone)) return next('输入的手机号不正确');

		} else if (request.type === 'email') {
			var reg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/;
			var email = request.username;
			if (!reg.test(email)) return next('输入的邮箱不正确');

		} else if (request.type === 'name') {
			var reg = /^([a-z0-9_].*){6,}$/;
			var name = request.username;
			if (!reg.test(name)) return next('长度必须大于6位，只能输入数字，或小写英文字母, 或下划线');

		} else {
			return next('注册类型错误！')
		}

		return next();
	}

	/**
	 * 查询一个用户信息
	 * @param next
	 */
	function findOneUser(next) {

		User.findOne({
				username: request.username
			})
			.exec(function(err, result) {
				if (err) {
					sails.log.error('MemberController.findOneUser:', err);
					return next({
						status: 500,
						error: err
					});
				}

				next(null, result);

			});
	};

	/**
	 * 创建一个用户
	 * @param user
	 * @param next
	 * @returns {*}
	 */
	function createUser(user, next) {

		if (user) {
			return next('用户名已经存在!');
		}

		User.create(request)
			.exec(function(err, result) {
				if (err) {
					return next(err);
				}
				return next(null, result);
			});

	};

	/**
	 * 从189开放平台，获取访问令牌
	 * @param  {Function} next
	 * @return {[type]}
	 */
	function getAccessToken(next) {

		var accessTokenUrl = sprintf(open189Config.accessTokenUrl, {
			appId: open189Config.appId,
			appSecret: open189Config.appSecret
		});

		//获取当前时间
		var nowTime = Date.now() / 1000;

		if (accessToken.endTime === 0 || accessToken.endTime < (nowTime - 120)) { //提前2分钟，获取访问令牌
			http.post({
				url: accessTokenUrl
			}, function(e, r, body) {
				var responseJson = JSON.parse(body);
				sails.log.debug('MemberController.getAccessToken', responseJson);

				var resCode = responseJson.res_code;
				if (resCode != 0) {
					return next(responseJson);
				}

				accessToken.token = responseJson.access_token;
				accessToken.endTime = nowTime + responseJson.expires_in;
				return next();
			});

		} else {
			return next();
		}

	};

	/**
	 * 根据访问令牌，从189开放平台获取信任码
	 * @param  {Function} next
	 * @return {[type]}
	 */
	function getToken(next) {

		//生成时间戳
		var date = new Date();

		var year = date.getFullYear();
		var month = date.getMonth() + 1;
		var day = date.getDate() + 1;
		var hours = date.getHours();
		var minutes = date.getMinutes();
		var seconds = date.getSeconds();

		if (month < 10) month = "0" + month;
		if (day < 10) day = "0" + day;
		if (hours < 10) hours = "0" + hours;
		if (minutes < 10) minutes = "0" + minutes;
		if (seconds < 10) seconds = "0" + seconds;

		var timestamp = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;

		//生成参数签名
		var args = "access_token=" + accessToken.token + "&app_id=" + open189Config.appId + "&timestamp=" + timestamp;

		var sign = require('crypto').createHmac('sha1', open189Config.appSecret)
			.update(args).digest().toString('base64');


		var tokenUrl = sprintf(open189Config.tokenUrl, {
			appId: open189Config.appId,
			accessToken: accessToken.token,
			timestamp: timestamp,
			sign: sign
		});

		http.get({
			url: tokenUrl
		}, function(e, r, body) {
			var responseJson = JSON.parse(body);
			sails.log.debug('MemberController.getToken', responseJson);

			var res_code = responseJson.res_code;
			if (res_code != 0) {
				return next({
					getToken: responseJson
				});
			}

			var token = responseJson.token;
			var randcodeToken = {
				token: token,
				timestamp: timestamp
			};
			return next(null, randcodeToken);
		});
	};

	/**
	 * 通过189平台，发送短信验证码
	 * @param  {[type]}   parameters
	 * @param  {Function} next
	 * @return {[type]}
	 */
	function sendSMSCode(randcodeToken, next) {

		var phone = request.username;
		var token = randcodeToken.token;
		var timestamp = randcodeToken.timestamp;
		var appId = open189Config.appId;
		var appSecret = open189Config.appSecret;

		//产生6位随机验证码
		var randcode = "";
		for (var i = 0; i < 6; i++) {
			randcode += Math.floor(Math.random() * 10);
		}

		//发送短信验证码至用户手机
		var args = "access_token=" + accessToken.token + "&app_id=" + appId + "&phone=" + phone + "&randcode=" + randcode + "&timestamp=" + timestamp + "&token=" + token;

		var sign = require('crypto').createHmac('sha1', appSecret)
			.update(args).digest().toString('base64');

		var randcodeUrl = sprintf(open189Config.randcodeUrl, {
			appId: appId,
			accessToken: accessToken.token,
			token: token,
			phone: phone,
			randcode: randcode,
			timestamp: timestamp,
			sign: sign
		});

		//间隔1秒钟，发送短信
		setTimeout(function() {
			http.post({
				url: randcodeUrl
			}, function(e, r, body) {
				var responseJson = JSON.parse(body);
				sails.log.debug('MemberController.sendCode', responseJson);

				var res_code = responseJson.res_code;
				if (res_code != 0) {
					return next({
						sendCode: responseJson
					});
				}

				return next(null, randcode);
			});

		}, 3000);

	}

	/**
	 * 通过手机短信发送激活码，最多重发三次。
	 * @param  {[type]}   user
	 * @param  {Function} next
	 * @return {[type]}
	 */
	function retrySendSMSValidateCode(next) {
		async.retry(3, sendSMSValidateCode, function(err, result) {
			if (err) {
				sails.log.error("MemberController.retrySendValidateCode", err);
				return next(err);
			}
			sails.log.debug("MemberController.retrySendSMSValidateCode", result);
			return next(null, result);
		});
	}

	/**
	 * 调用189开放平台，发送激活码
	 * @param  {Function} callback
	 * @param  {[type]}   results
	 * @return {[type]}
	 */
	function sendSMSValidateCode(callback, results) {

		async.waterfall([
			getAccessToken,
			getToken,
			sendSMSCode
		], function(err, result) {
			if (err) {
				return callback(err);
			}

			sails.log.debug('MemberController.sendSMSValidateCode', result);
			return callback(null, result);
		});
	}

	/**
	 * 创建激活用户数据。
	 * @param  {[type]}   randcode
	 * @param  {Function} next
	 * @return {[type]}
	 */
	function createActiveUser(randcode, next) {

		var activeUser = {
			username: request.username,
			type: request.type,
			validateCode: randcode
		};

		ActiveUser.create(activeUser)
			.exec(function(err, result) {
				if (err) {
					sails.log.error("MemberController.createActiveUser", err);
					return next(err);
				}
				return next(null, result);
			});
	}

	/**
	 * 用户修改密码之前校验
	 * @param  {Function} next [description]
	 * @return {[type]}        [description]
	 */
	function validateModifyPassword(session, next) {

		if (session.user == null) {
			return next('用户没有登录');
		}

		if (!request.username) {
			return next('用户名必须输入');
		}

		if (session.user.username != request.username) {
			return next('只允许修改个人密码');
		}

		if (!request.password) {
			return next('旧密码必须输入');
		}

		if (!request.newPassword) {
			return next('新密码必须输入');
		}

		async.waterfall([
			findOneUser
		], function(err, user){
			if (err) {
				return next(err);
			}

			if (user.validPassword(request.password)) {
				var updateInfo = {
					username: request.username,
					password: request.newPassword
				}
				return next(null, updateInfo);

			} else {
				return next('密码输入错误')
			}

		})

	}

	function validateModifyInfo(session, next) {

		if (session.user == null) {
			return next('用户没有登录');
		}

		if (!request.username) {
			return next('用户名不存在');
		}

		if (session.user.username != request.username) {
			return next('只允许修改个人信息');
		};

		var updateInfo = {username: request.username};
		if (request.avatar) updateInfo.avatar = request.avatar;
		if (request.nickname) updateInfo.nickname = request.nickname;
		if (request.gender) updateInfo.gender = request.gender;
		if (request.introduction) updateInfo.introduction = request.introduction;
		return next(null, updateInfo)
	}

	/**
	 * 更改用户信息
	 * @param  {[type]}   updateInfo [description]
	 * @param  {Function} next       [description]
	 * @return {[type]}              [description]
	 */
	function updateUser(updateInfo, next) {

		User.update({
				username: updateInfo.username
			}, updateInfo)
			.exec(function(error, results) {
				if (error) {
					return next(error);
				}

				var result = results[0];
				if (_.has(result, 'id')) {
					return next(null, result);
				} else {
					return next('用户名不存在!');
				}

			});
	};

	/**
	 * 通过手机短信发送激活码，生成激活用户。
	 * @param  {[type]} req
	 * @param  {[type]} res
	 * @return {[type]}
	 */
	MemberController.smsActiveUser = function(req, res) {
		root.request = req.body;
		request.type = 'phone'; //标识激活类型

		async.waterfall([
			retrySendSMSValidateCode,
			createActiveUser,
		], function(err, result) {
			if (err) {
				if (_.has(err, 'status')) {
					return res.jsonResponse(err.status, err.error);
				} else {
					return res.jsonResponse(400, err);
				}
			}

			return res.jsonResponse(200, '已经激活成功！');
		});
	};

	/**
	 * 会员注册
	 * @param  {[type]} req
	 * @param  {[type]} res
	 * @return {[type]}
	 */
	MemberController.signup = function(req, res) {
		root.request = req.body;

		async.waterfall([
			validateSignup,
			findOneUser,
			createUser
		], function(err, result) {

			if (err) {
				if (_.has(err, 'status')) {
					return res.jsonResponse(err.status, err.error);
				} else {
					return res.jsonResponse(400, err);
				}
			}

			return res.jsonResponse(200, '用户已经注册成功！');

		});

	};

	/**
	 * 用户修改个人密码
	 * @param  {[type]} req [description]
	 * @param  {[type]} res [description]
	 * @return {[type]}     [description]
	 */
	MemberController.modifyPassword = function(req, res) {
		root.request = req.body;

		async.waterfall([
			async.apply(validateModifyPassword, req.session),
			updateUser
		], function(err, result) {

			if (err) {
				if (_.has(err, 'status')) {
					return res.jsonResponse(err.status, err.error);
				} else {
					return res.jsonResponse(400, err);
				}
			}

			return res.jsonResponse(200, '修改密码成功！');

		});
	};

	/**
	 * 用户修改个人信息
	 * @param  {[type]} req [description]
	 * @param  {[type]} res [description]
	 * @return {[type]}     [description]
	 */
	MemberController.modifyInfo = function(req, res) {
		root.request = req.body;

		async.waterfall([
			async.apply(validateModifyInfo, req.session),
			updateUser
		], function(err, result) {

			if (err) {
				if (_.has(err, 'status')) {
					return res.jsonResponse(err.status, err.error);
				} else {
					return res.jsonResponse(400, err);
				}
			}

			return res.jsonResponse(200, '修改个人信息成功！');


		});
	};

	/**
	 * 查询用户个人信息
	 * @param  {[type]} req [description]
	 * @param  {[type]} res [description]
	 * @return {[type]}     [description]
	 */
	MemberController.memberInfo = function(req, res) {
		root.request = req.body;

		async.waterfall([
			findOneUser
		], function(err, result) {

			if (err) {
				return res.jsonResponse(400, err);
			}

			if (_.has(result, 'id')) {
				res.jsonResponse(200, result);
			}

		});
	};

	module.exports = MemberController;
}());